/**
 * @description ui管理
 * @date 2024.9.10
 * @author wz
 * @midify 2025.5.9
 * @editor wz
 */
import { _decorator, Constructor, Node } from 'cc';
import { Singleton } from '../../utils/Singleton';
import { UIPipeline } from './UIPipeline';
import { UIBase } from './UIBase';
import { ProxyBase } from '../proxy/ProxyBase';
import { proxyMgr } from '../proxy/ProxyMgr';
import { js } from 'cc';
import { UIMeta, UIState } from './BaseTypes';

/**
 * ui管理
 */
export class UIMgr extends Singleton {
    readonly uiMetaMap: Map<string, UIMeta> = new Map();

    private _pipelineMap: Map<number, UIPipeline> = null;

    /**
     * 初始化层级
     * @param layerMap 
     */
    init(layerMap: Map<number, { root: Node, water: number }>) {
        this._pipelineMap = new Map();
        layerMap.forEach((node, layer) => {
            const pipline = new UIPipeline()
            pipline.init(node.root, node.water);
            this._pipelineMap.set(layer, pipline);
        });
    }

    /**
     * 获取指定层级的UI管道
     * @param layer 
     * @returns 
     */
    private _getPipeline(layer: number): UIPipeline {
        if (!this._pipelineMap.has(layer)) {
            console.warn(`UIMgr>>>getPipeline>>>layer:${layer} not found`);
            return null;
        }
        return this._pipelineMap.get(layer);
    }

    private _checkHasPipeline(layer: number): boolean {
        if (!this._pipelineMap.has(layer)) {
            console.warn(`UIMgr>>>getPipeline>>>layer:${layer} not found`);
            return false;
        }
        return true;
    }

    /**
     * 获取层
     * @param proxyClass 
     * @returns 
     */
    private _getLayer(proxyClass: Constructor<ProxyBase> | string) {
        const proxyName = typeof proxyClass === 'string' ? proxyClass : proxyClass.name;
        const meta = proxyMgr.getMetaByProxy(proxyName)
        if (!meta) {
            console.warn(`UIMgr>>>getLayer>>>proxy:${meta.proxyName} not found`);
            return
        }
        if (!this.uiMetaMap.has(proxyName)) {
            console.warn(`UIMgr>>>show>>>UIBase:${proxyName} not found in uiMetaMap`);
            return
        }
        if (!js.isChildClassOf(meta.ctor, UIBase)) {
            console.warn(`UIMgr>>>show>>>proxy:${proxyName} is not a UIBase`);
            return
        }
        const metaUI = this.uiMetaMap.get(proxyName);
        if (!this._checkHasPipeline(metaUI.layer)) return
        return metaUI.layer;
    }

    /**
     * 显示UI界面
     * @param proxyClass 代理类型
     * @param data 传入的参数
     * @param showCallback 显示回调
     * @param closeCallback 关闭回调
     * @returns 
     */
    async show(proxyClass: Constructor<ProxyBase> | string, data?: any, showCallback?: Function, closeCallback?: Function) {
        const layer = this._getLayer(proxyClass);
        if (layer !== null) return this._getPipeline(layer).show(proxyClass, { data, showCallback, closeCallback });
    }

    /**
     * 关闭UI界面
     * @param proxyClass 
     * @returns 
     */
    close(proxyClass: Constructor<ProxyBase> | string) {
        const layer = this._getLayer(proxyClass);
        if (layer !== null) return this._getPipeline(layer).close(proxyClass);
    }

    /**
     * 关闭层的所有UI界面
     * @param layer 
     * @returns 
     */
    closeLayer(layer: number) {
        if (!this._checkHasPipeline(layer)) return
        this._pipelineMap.get(layer).closeAll();
    }

    /**
     * 关闭所有UI界面
     */
    closeAll() {
        this._pipelineMap.forEach(pipeline => {
            pipeline.closeAll();
        });
    }

    /**
     * 返回到指定界面
     * @param layer 
     * @param proxy 
     * @returns 
     */
    backToTop(layer: number, proxyClass: Constructor<ProxyBase> | string) {
        if (layer !== this._getLayer(proxyClass)) {
            console.warn(`UIMgr>>>backToTop>>>layer:${layer} not match meta.layer:${layer}`);
            return;
        }
        this._getPipeline(layer).backToTop(proxyClass);
    }

    /**
     * 主动释放(只有已关闭界面才行)
     * @param proxyClass 
     * @returns 
     */
    release(proxyClass: Constructor<ProxyBase> | string) {
        const layer = this._getLayer(proxyClass);
        if (layer !== null) return this._getPipeline(layer).release(proxyClass);
    }

    /**
     * 主动释放层的所有界面
     * @param layer 
     * @returns 
     */
    releaseLayer(layer: number) {
        if (!this._checkHasPipeline(layer)) return;
        const pipeline = this._pipelineMap.get(layer);
        if (pipeline) {
            pipeline.releaseAll();
        }
    }

    /**
     * 所有界面都释放
     */
    releaseAll() {
        if (!this._pipelineMap || this._pipelineMap.size === 0) return;
        this._pipelineMap.forEach(pipeline => {
            if (pipeline) {
                pipeline.releaseAll();
            }
        });
    }

    /**
     * 获取界面信息
     * @param proxy 
     * @returns 
     */
    getInfo(proxyClass: Constructor<ProxyBase> | string) {
        const layer = this._getLayer(proxyClass);
        if (layer !== null) return this._getPipeline(layer).getInfo(proxyClass);
    }

    /**
     * 获取状态
     * @param proxyClass 
     * @returns 
     */
    getState(proxyClass: Constructor<ProxyBase> | string) {
        return this.getInfo(proxyClass)?.state || UIState.NONE
    }

    /**
     * 获取ui元数据
     * @param proxyClass 
     * @returns 
     */
    getUIMeta(proxyClass: Constructor<ProxyBase> | string): UIMeta | undefined {
        const proxyName = typeof proxyClass === 'string' ? proxyClass : proxyClass.name;
        return this.uiMetaMap.get(proxyName);
    }
}

/**
 * ui管理器
 */
export const uiMgr: UIMgr = UIMgr.getInstance<UIMgr>();


